package main

import (
	"fmt"
	"reflect"
	codecs "sanguo/codec/cs"
	"sanguo/cs"
	cs_msg "sanguo/protocol/cs/message"
	"time"

	"github.com/golang/protobuf/proto"
	"github.com/sniperHW/kendynet"
)

type handler func(kendynet.StreamSession, *codecs.Message)

type dispatcher struct {
	handlers map[string]handler
}

func (this *dispatcher) Register(msg proto.Message, h handler) {
	msgName := reflect.TypeOf(msg).String()
	if nil == h {
		return
	}
	_, ok := this.handlers[msgName]
	if ok {
		return
	}

	this.handlers[msgName] = h
}

func (this *dispatcher) Dispatch(session kendynet.StreamSession, msg *codecs.Message) {
	if nil != msg {
		name := msg.GetName()
		handler, ok := this.handlers[name]
		if ok {
			handler(session, msg)
		}
	}
}

func (this *dispatcher) OnEstablish(session kendynet.StreamSession) {
	fmt.Printf("OnEstablish\n")
	go func() {
		for {
			fmt.Println("1:Login服 2:Game服 3:重登 4:serverList")
			fmt.Println("5:createRole 6:roleList ")
			var i int
			fmt.Printf("测试: ")
			fmt.Scan(&i)
			switch i {
			case 1:
				LoginToS := &cs_msg.LoginToS{}
				LoginToS.UserID = proto.String("123")
				err := session.Send(codecs.NewMessage(0, LoginToS))
				if nil != err {
					fmt.Printf("send error:%s\n", err.Error())
				}
			case 2:
				gameToS := &cs_msg.GameLoginToS{}
				gameToS.ServerID = proto.Int32(2)
				gameToS.UserID = proto.String("123")
				gameToS.Token = proto.String("token123")
				err := session.Send(codecs.NewMessage(0, gameToS))
				if nil != err {
					fmt.Printf("send error:%s\n", err.Error())
				}
			case 3:
				gameToS := &cs_msg.ReconnectToS{}
				gameToS.UserID = proto.String("123")
				gameToS.Token = proto.String("token123")
				err := session.Send(codecs.NewMessage(0, gameToS))
				if nil != err {
					fmt.Printf("send error:%s\n", err.Error())
				}
			case 4:
				gameToS := &cs_msg.ServerListToS{}
				gameToS.UserID = proto.String("74125")
				err := session.Send(codecs.NewMessage(0, gameToS))
				if nil != err {
					fmt.Printf("send error:%s\n", err.Error())
				}
			case 5:
				fmt.Printf("角色名字:")
				var name string
				fmt.Scan(&name)
				req := &cs_msg.CreateRoleToS{
					Face:      proto.Int32(1),
					Hair:      proto.Int32(1),
					HairColor: proto.Int32(1),
					EyeColor:  proto.Int32(1),
					Cloth:     proto.Int32(1),
					Outline:   proto.Int32(1),
					Name:      proto.String(name),
				}
				err := session.Send(codecs.NewMessage(0, req))
				if nil != err {
					fmt.Printf("send error:%s\n", err.Error())
				}
			case 6:
				req := &cs_msg.RoleListToS{}
				err := session.Send(codecs.NewMessage(0, req))
				if nil != err {
					fmt.Printf("send error:%s\n", err.Error())
				}
			}
			time.Sleep(time.Millisecond * 500)
		}
	}()
}

func (this *dispatcher) OnClose(session kendynet.StreamSession, reason string) {
	fmt.Printf("connection lose:%s\n", reason)
}

func (this *dispatcher) OnConnectFailed(peerAddr string, err error) {
	fmt.Printf("OnConnectFailed\n")
}

func main() {
	d := &dispatcher{handlers: make(map[string]handler)}
	d.Register(&cs_msg.LoginToC{}, LoginToC)
	d.Register(&cs_msg.GameLoginToC{}, GameLoginToC)
	d.Register(&cs_msg.ServerListToC{}, ServerList)
	d.Register(&cs_msg.CreateRoleToC{}, CreateRole)
	d.Register(&cs_msg.RoleListToC{}, RoleListToC)
	d.Register(&cs_msg.SelectRoleToC{}, SelectRoleToC)

	fmt.Printf("压力测试: 1:dir服 2:game服 ==>")
	var i int
	fmt.Scan(&i)
	switch i {
	case 1:
		cs.DialTcp("10.128.2.153:9012", 0, d)
		fmt.Printf("\n")
	case 2:
		cs.DialTcp("10.128.2.153:9010", 0, d)
		fmt.Printf("\n")
	}
	sigStop := make(chan bool)
	_, _ = <-sigStop
}

func LoginToC(session kendynet.StreamSession, msg *codecs.Message) {
	LoginToC := msg.GetData().(*cs_msg.LoginToC)
	fmt.Println("GetCode:", LoginToC.GetCode())
	fmt.Println("GetGame :", LoginToC.GetGame())
	fmt.Println("GetToken :", LoginToC.GetToken())
}

func GameLoginToC(session kendynet.StreamSession, msg *codecs.Message) {
	gameLoginToC := msg.GetData().(*cs_msg.GameLoginToC)
	fmt.Println("GetCode:", gameLoginToC.GetCode())
}

func ReconnectToC(session kendynet.StreamSession, msg *codecs.Message) {
	gameLoginToC := msg.GetData().(*cs_msg.ReconnectToC)
	fmt.Println("GetCode:", gameLoginToC.GetCode())
}

func ServerList(session kendynet.StreamSession, msg *codecs.Message) {
	serverListToC := msg.GetData().(*cs_msg.ServerListToC)
	fmt.Println("ServerList")
	for _, v := range serverListToC.ServerList {
		fmt.Println("---------------------")
		fmt.Println("UserType :", v.GetUserType())
		fmt.Println("ServerType :", v.GetServerType())
		fmt.Println("GetServerId :", v.GetServerId())
		fmt.Println("GetServerName :", v.GetServerName())
		fmt.Println("GetServerAddr :", v.GetServerAddr())
		fmt.Println("GetPNum :", v.GetPlayerNum())
		fmt.Println("GetPLevel :", v.GetPLevel())
	}

}

func CreateRole(session kendynet.StreamSession, msg *codecs.Message) {
	resq := msg.GetData().(*cs_msg.CreateRoleToC)
	fmt.Println("CreateRole", resq)
}

func RoleListToC(session kendynet.StreamSession, msg *codecs.Message) {
	resq := msg.GetData().(*cs_msg.RoleListToC)
	fmt.Println("RoleListToC")
	for _, v := range resq.RoleList {
		fmt.Println("---------------------")
		fmt.Println(v)

	}
}

func SelectRoleToC(session kendynet.StreamSession, msg *codecs.Message) {
	resq := msg.GetData().(*cs_msg.SelectRoleToC)
	fmt.Println("CreateRole", resq)
}
